<template>
  <div>
    <el-form :model="spu" label-width="120px">
      <el-form-item label="SPU名称">
        <el-input v-model="spu.spuName" placeholder="请输入SPU名称"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
        <el-select v-model="spu.tmId" placeholder="请选择品牌">
          <el-option
            v-for="item in tradeMarkList"
            :key="item.id"
            :label="item.tmName"
            :value="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input
          v-model="spu.description"
          type="textarea"
          placeholder="请输入SPU描述"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <el-upload
          action="/api/admin/product/fileUpload"
          v-model:file-list="imageList"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
      </el-form-item>
      <el-form-item label="SPU销售属性">
        <el-select
          style="width: 200px; margin-right: 10px"
          v-model="attrId"
          :disabled="!unSelectSaleAttr.length"
          :placeholder="
            unSelectSaleAttr.length ? '请选择销售属性' : '暂无销售属性可选择'
          "
        >
          <el-option
            v-for="item in unSelectSaleAttr"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          :disabled="!attrId"
          @click="addAttr"
          icon="Plus"
          >添加销售属性</el-button
        >
        <el-table :data="spu.spuSaleAttrList" border style="margin: 10px 0">
          <el-table-column
            label="序号"
            type="index"
            width="80px"
            align="center"
          />
          <el-table-column label="属性名" prop="saleAttrName" width="150px" />
          <el-table-column label="属性值">
            <template #="{ row, $index }">
              <el-tag
                style="margin-right: 10px"
                v-for="(item, index) in row.spuSaleAttrValueList"
                :key="index"
                closable
                @close="deleteAttrValue(row, index)"
                >{{ item.saleAttrValueName }}</el-tag
              >
              <el-input
                v-if="row.inputVisible"
                v-model.trim="row.input"
                placeholder="请输入属性值"
                style="width: 200px; margin-right: 10px"
                @blur="handleInputConfirm(row)"
                :ref="(el: any) => (inputList[$index] = el)"
              />
              <el-button
                type="success"
                size="small"
                icon="Plus"
                @click="addAttrValue(row, $index)"
                v-if="!row.inputVisible"
              ></el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="80px" align="center">
            <template #="{ row, $index }">
              <el-popconfirm
                :title="`是否删除${row.saleAttrName}？`"
                icon="Delete"
                width="220"
                @confirm="deleteAttr($index)"
              >
                <template #reference>
                  <el-button
                    type="danger"
                    icon="Delete"
                    size="small"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          @click="save"
          :disabled="!spu.spuSaleAttrList.length"
          >保存</el-button
        >
        <el-button @click="cancel">取消</el-button>
      </el-form-item>
    </el-form>
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="图片预览" />
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, toRefs, computed, nextTick } from 'vue'
import {
  getBaseSaleAttrList,
  getTradeMarkList,
  getSpuImageList,
  getSpuInfo,
  addOrUpdateSpu
} from '@/api/product/spu'
import useCategoryStore from '@/store/modules/category'
import { ElMessage } from 'element-plus'
import type { UploadProps } from 'element-plus'

const categoryStore = useCategoryStore()
const { category3Id } = toRefs(categoryStore)

const spu = reactive<any>({
  category3Id: '',
  description: '',
  id: '',
  spuImageList: [],
  spuName: '',
  spuSaleAttrList: [],
  tmId: ''
})

let attrId = ref<string>('')
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}
const deleteAttr = (index: number) => {
  spu.spuSaleAttrList.splice(index, 1)
}
const deleteAttrValue = (row: any, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1)
}
const addAttrValue = (row: any, index: number) => {
  row.inputVisible = true
  row.input = ''
  nextTick(() => {
    inputList.value[index].focus()
  })
}
const handleInputConfirm = (row: any) => {
  if (!row.input) {
    row.inputVisible = false
    return
  }

  const result = row.spuSaleAttrValueList.find(
    (item: any) => item.saleAttrValueName === row.input
  )
  if (result) return ElMessage.error('属性值不能重复')

  row.spuSaleAttrValueList.push({
    saleAttrValueName: row.input,
    baseSaleAttrId: row.baseSaleAttrId
  })
  row.inputVisible = false
  ElMessage.success(`新增属性值成功`)
}

const baseSaleAttrList = ref<any>([])
const getBaseSaleAttrListFun = () => getBaseSaleAttrList()
const tradeMarkList = ref<any>([])
const getTradeMarkListFun = () => getTradeMarkList()
const imageList = ref([])
const getSpuImageListFun = (spuId: string | number) => getSpuImageList(spuId)
const getSpuInfoFun = (spuId: string | number) => getSpuInfo(spuId)
const getBaseList = async (spuId: string | number | undefined) => {
  reset()
  const baseSaleAttrListResult = await getBaseSaleAttrListFun()
  if (baseSaleAttrListResult.code === 200)
    baseSaleAttrList.value = baseSaleAttrListResult.data
  const tradeMarkListResult = await getTradeMarkListFun()
  if (tradeMarkListResult.code === 200)
    tradeMarkList.value = tradeMarkListResult.data

  if (spuId) {
    const spuImageListResult = await getSpuImageListFun(spuId)
    if (spuImageListResult.code === 200) {
      imageList.value = spuImageListResult.data.map((item: any) => {
        return { name: item.imgName, url: item.imgUrl }
      })
    }
    const spuInfoResult = await getSpuInfoFun(spuId)
    if (spuInfoResult.code === 200) Object.assign(spu, spuInfoResult.data)
  }
}

const addAttr = () => {
  spu.spuSaleAttrList.push({
    baseSaleAttrId: attrId.value,
    id: '',
    saleAttrName: baseSaleAttrList.value.find(
      (item: any) => item.id === attrId.value
    )?.name,
    spuId: '',
    spuSaleAttrValueList: []
  })
  attrId.value = ''
}

const emit = defineEmits(['closed'])
const cancel = () => {
  emit('closed')
}
const reset = () => {
  Object.assign(spu, {
    category3Id: '',
    description: '',
    id: '',
    spuImageList: [],
    spuName: '',
    spuSaleAttrList: [],
    tmId: ''
  })
  baseSaleAttrList.value = []
  tradeMarkList.value = []
  imageList.value = []
  attrId.value = ''
  inputList.value = []
}
const save = async () => {
  spu.category3Id = category3Id.value
  spu.spuImageList = imageList.value.map((item: any) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
      spuId: spu.id
    }
  })
  const result = await addOrUpdateSpu(spu)
  if (result.code === 200) {
    ElMessage.success('保存成功')
    cancel()
  } else {
    ElMessage.error('保存失败')
  }
}
defineExpose({ getBaseList })

const unSelectSaleAttr = computed(() =>
  spu.spuSaleAttrValueList
    ? baseSaleAttrList.value.filter((item: any) => {
        return spu.spuSaleAttrValueList.every((attr: any) => {
          return attr.baseSaleAttrId !== item.id
        })
      })
    : baseSaleAttrList.value
)

const inputList = ref<any[]>([])
</script>

<style lang="scss" scoped></style>
